package com.demo.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;

/**
 * @author wangfengchen
 */
@Slf4j
public class HttpClientUtil {


  private static final ObjectMapper MAPPER = new ObjectMapper();


  /**
   * 同步get方法
   *
   * @param url
   * @throws Exception
   */
  private static void syncGet(String url) throws Exception {
    HttpClient client = HttpClient.newBuilder()
        .version(HttpClient.Version.HTTP_2)
        .connectTimeout(Duration.ofSeconds(30))
        .followRedirects(HttpClient.Redirect.ALWAYS)
        .build();
    HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).GET().build();
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    log.info("code = {}", response.statusCode());
    log.info("body = {}", response.body());
  }

  /**
   * 异步get方法
   *
   * @param url
   * @throws Exception
   */
  private static void asyncGet(String url) throws Exception {
    HttpClient client = HttpClient.newBuilder()
        .version(HttpClient.Version.HTTP_2)
        .connectTimeout(Duration.ofSeconds(30))
        .followRedirects(HttpClient.Redirect.ALWAYS)
        .build();
    HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).GET().build();
    CompletableFuture<HttpResponse<String>> future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
    future.whenComplete((response, throwable) -> {
      if (throwable != null) {
        throwable.printStackTrace();
      } else {
        log.info("code = {}", response.statusCode());
        log.info("body = {}", response.body());
      }
    }).join();
  }

  private static void syncPost(String url, Object data) throws Exception {
    HttpClient client = HttpClient.newBuilder()
        .version(HttpClient.Version.HTTP_2)
        .connectTimeout(Duration.ofSeconds(30))
        .followRedirects(HttpClient.Redirect.ALWAYS)
        .build();
    HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url))
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(encodeData(data)))
        .build();
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    log.info("code = {}", response.statusCode());
    log.info("body = {}", response.body());
  }

  public static String encodeData(Object data) {
    if (data == null) {
      return "";
    }
    boolean json = isJson(data.toString());
    if (json) {
      return (String) data;
    }
    try {
      return MAPPER.writeValueAsString(data);
    } catch (JsonProcessingException e) {
      log.error("序列化json数据异常，exception = {}", ExceptionUtils.getStackTrace(e));
      throw new RuntimeException(e);
    }
  }

  public static boolean isJson(String input) {
    ObjectMapper mapper = new ObjectMapper();
    try {
      // 尝试将字符串解析为JsonNode树状结构（对象或数组）
      mapper.readTree(input);
      return true;
    } catch (Exception e) {
      return false;
    }
  }



  public static void main(String[] args) throws Exception {
    String getUrl = "http://t.weather.sojson.com/api/weather/city/101030100";
    String postUrl = "https://jsonplaceholder.typicode.com/posts";
    String data = "{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}";
//    syncGet(getUrl);
//    asyncGet(getUrl);
    syncPost(postUrl, data);
  }


}
